_files/1481034980961904.jpg)
之前的文章中,我们提到了shell中常用的字符串处理操作,我们来回顾一下
一、获取变量的长度(字符串长度)。
二、对变量值进行截取(截取字符串)。
三、替换变量值中的某段字符。
四、删除变量值中的某段字符。
五、对变量值进行大小写转换。
六、当变量值为空时,对变量进行一些操作。
前两篇文章中,我们已经总结了上述操作中的前四种操作,今天,我们来介绍一下上述操作的最后两种操作,并将之前的所有总结进行一个汇总,以便以后进行回顾。
字符串大小写转换
首先,我们准备一个变量,变量值为字母a到z,只不过a到k为小写,L到Z为大写,如下图所示
_files/091017_0925_1.png)
如果我们想要将变量testvar1中的所有小写英文字母都转换成大写,该怎么办呢?我们可以使用如下方法。
_files/091017_0925_2.png)
如上图所示,只要在输出变量值时加上"^^"即可,"^"为数字键6对应的符号。
如果想要将变量testvar1中的所有大写英文字母都转换成小写,可以使用如下方法。
_files/091017_0925_3.png)
如上图所示,只要在输出变量值时加上",,"即可将字母中的大写字符转换成小写,很简单吧~
当变量值为空或者非空时对变量进行操作
在写shell脚本时,我们可能会遇到如下场景。
我们需要判断某个变量是否为空,如果变量值不为空,则使用变量当前的值,如果为空,则赋予变量一个默认值,以便之后进行处理。
那么,在脚本中可能会出现类似如下代码
if [ -z "$testvar" ];then
testvar="test"
fi
如上述代码所示,我们使用 if 结构,判断了变量testvar是否为空,如果为空,则将变量赋值为test,当然,如果变量值不为空,那么则不会被赋值,即保持变量原值不变。
其实,我们可以使用更简单的方法,我们只需要一行代码,就可以代替上例中的三行代码,示例如下
${testvar:="test"}
没错,就是这么简单,上述代码表示,如果变量testvar的值为空,则将testvar赋值为test,如果不为空,则testvar保持原值不变。我们在命令行中试试上述代码的效果,首先,将变量testvar的值设置为空值,然后使用上述语法,如下。
_files/blank.gif)
可以看到,当变量为空时,上述语法不仅会将变量的值设置为指定值,同时还会返回对应的值,我们可以直接使用echo命令进行输出,经过上述语法处理后,再次输出变量,变量已经被赋值。
当变量值不为空时,经过上述语法处理后,只会返回变量的原值,并不会改变变量的值,示例如下
_files/blank.gif)
可以发现,当变量为空时,使用上述语法会返回我们指定的值,同时还会将变量设定为我们指定的值,其实,还有另外一种方法,能够在变量为空时返回我们指定的值,但是不对变量进行赋值,示例如下。
${testvar:-"test"}
细心如你一定发现了,与之前的语法相比,只是语法中的"="替换成了"-"
上述语法表示,如果testvar变量值为空,则返回指定的文本"test",如果testvar变量值不为空,则返回testvar变量本身的值,但是,当testvar变量值为空时,使用上述语法,只会返回指定的值,并不会对变量进行赋值操作,我们在命令行中看一下效果,示例如下。
_files/blank.gif)
可以看到,当变量为空时,上述语法并不会对变量赋值,当变量值不为空时,示例如下。
_files/blank.gif)
之前的两个示例,都是在变量为空时,返回我们指定的值,那么能不能在变量不为空时,返回我们指定的值呢?必须能的,使用如下语法即可。
${testvar:+"test"}
上述语法表示,当testvar变量值不为空时,返回指定的字符串"test",如果变量为空,则返回变量本身的值(即空值),示例如下
_files/blank.gif)
如上图所示,当变量值不为空时,使用上述语法会返回我们指定的值,但是并不会改变变量原来的值,如果变量值为空,使用上述语法,仍然返回空值,同时也不会对变量进行赋值。
我们还可以在变量为空时,输出bash风格的error_info,示例如下
${testvar:?"error_info"}
上述语法表示testvar变量为空时,输出bash错误,错误信息为我们指定的字符串error_info
示例如下
_files/blank.gif)
总结
为了方便以后回顾,我们将之前所有与字符串处理、变量处理的相关操作进行汇总,并进行一个总结。
获取字符串长度
|
|
# testvar="12345" # echo ${#testvar} 5 |
对变量值进行大小写转换
将变量值中的小写字母装换为大写
语法:echo ${var^^}
|
|
#示例 # testvar="case conversion" # echo ${testvar} case conversion # echo ${testvar^^} CASE CONVERSION |
将变量值中的小写字母装换为大写
语法:echo ${var^^}
|
|
#示例 # testvar="CASE CONVERSION" # echo ${testvar} CASE CONVERSION # echo ${testvar,,} case conversion |
当变量值为空或者非空时操作变量
${var:=value}
上述语法表示如果var为空,则返回value,并将value赋值给var,如果var不为空,则返回var本身的值,var不为空时,var值不会被改变,var为空时,var的值会被设置成指定值。
${var:-value}
上述语法表示如果var为空,则返回value,如果var不为空,则返回var的值,无论var是否为空,var本身的值不会改变。
${var:+value}
上述语法表示如果var不为空,则返回value,如果var为空,则返回空值,无论var是否为空,var本身的值不会改变。
${var:?error_info}
上述语法表示如果var为空,那么在当前终端打印error_info,如果var的值不为空,则返回var的值,无论var是否为空,var本身的值都不会改变。
从指定位置截取字符串,截取到字符串的末尾
#下例表示从正数第4个字符以后开始截取,直到字符串的末尾。
|
|
# website="www.zsythink.net" # echo ${website:4} zsythink.net |
#下例表示从倒数第4个字符开始截取,直到字符串的末尾
#注意:下例中的"负号"与"冒号"之间必须存在任意字符(通常使用0或空格占位),否则无法起到截取字符串的作用。
|
|
# website="www.zsythink.net" # echo ${website:0-4} .net # echo ${website: -4} .net # echo ${website:a-4} .net |
从指定位置截取字符串,并且截取指定的长度
#下例表示从正数第4个字符以后开始截取,截取8个字符。
|
|
# website="www.zsythink.net" # echo ${website:4:8} zsythink |
#下例表示从倒数第9个字符开始截取,截取5个字符。
|
|
# website="www.zsythink.net" # echo ${website:0-9:5} think |
##centos7中,截取长度可以为负数,centos6中不行,centos7中的示例如下
#下例表示从正数第4个字符以后开始截取,截取到字符串的末尾,再将截取后的字符串的最后3个字符删除。
|
|
# website="www.zsythink.net" # echo ${website:4:-3} zsythink. |
##centos7中,截取长度可以为负数,centos6中不行,centos7中的示例如下
#下例表示从倒数第4个字符开始截取,截取到字符串的末尾,再将截取后的字符串的最后1个字符删除。
|
|
# website="www.zsythink.net" # echo ${website:0-4:-1} .ne |
掐头去尾截取之掐头截取
掐头截取:删除字符串中从左向右第一个遇到的char,以及其左侧的字符
##语法:${var#*char}
|
|
#下例表示删除字符串中从左向右第一个遇到的 "." ,以及其左侧的字符。 # website="www.zsythink.net" # echo ${website#*.} zsythink.net #下例表示删除字符串中从左向右第一个遇到的 "//" ,以及其左侧的字符。 # website="https://ww.zsythink.net" # echo ${website#*//} ww.zsythink.net |
掐头截取:删除字符串中从左向右最后一个遇到的char,以及其左侧的字符
##语法:${var##*char}
|
|
#下例表示删除字符串中从左向右最后一个遇到的 "/" ,以及其左侧的字符。 # website="https://ww.zsythink.net/index.html" # echo ${website##*/} index.html #下例表示删除字符串中从左向右最后一个遇到的 "." ,以及其左侧的字符。 # website="www.zsythink.net" # echo ${website##*.} net |
掐头去尾截取之去尾截取
去尾截取:删除字符串中从右向左第一个遇到的char,以及其右侧的字符
##语法:${var%char*}
|
|
#下例表示删除字符串中从右向左第一个遇到的 "/" ,以及其右侧的字符。 # testpath="/usr/local/nginx/conf.d" # echo ${testpath%/*} /usr/local/nginx #下例表示删除字符串中从右向左第一个遇到的 "@" ,以及其右侧的字符。 # testmail="zsy@zsythink.net" # echo ${testmail%@*} zsy |
去尾截取:删除字符串中从右向左最后一个遇到的char,以及其右侧的字符
##语法:${var%%char*}
|
|
#下例表示删除字符串中从右向左最后一个遇到的 "/" ,以及其右侧的字符。 # website="https://ww.zsythink.net/index.html" # echo ${website%%/*} https: #下例表示删除字符串中从右向左最后一个遇到的 ":" ,以及其右侧的字符。 # testpasswd="root:x:0:0:root:/root:/bin/bash" # echo ${testpasswd%%:*} root |
删除字符串的操作
删除变量值中第一个遇到的指定字符串
语法:echo ${var/str}
|
|
#下例表示删除变量值中第一个遇到的"@" # teststr="zsy@think@linux" # echo ${teststr/@} zsythink@linux |
删除变量值中所有的指定字符串
语法:echo ${var//str}
|
|
#下例表示删除字符串中所有的"@" # teststr="zsy@think@linux" # echo ${teststr//@} zsythinklinux |
特殊情况
|
|
刚才总结了两种语法 语法一:删除变量值中所有的指定字符串的语法为echo ${var//str} 语法二:删除变量值中第一个遇到的指定字符串的语法为echo ${var/str} 如果,我们要删除字符串"/usr/local/chroot/usr/local"中第一个遇到的"/usr",该怎么办呢? 正常情况下,我们会套用上述语法二,将语法二中的"str"更改为"/usr",套用语法二后的命令如下 # teststr="/usr/local/chroot/usr/local/nginx" # echo ${teststr//usr} 但是,套用语法二后的命令正好与上述语法一的语法结构相同,所以,本意是删除字符串中第一个遇到的"/usr",但是最终结果却变为删除字符串中所有的"usr",执行结果如下 # teststr="/usr/local/chroot/usr/local/nginx" # echo ${teststr//usr} //local/chroot//local/nginx 聪明如你一定想到了,这种情况需要对"/"进行转义,示例如下 # teststr="/usr/local/chroot/usr/local/nginx" # echo ${teststr/\/usr} /local/chroot/usr/local/nginx |
删除变量值中位于行首的指定字符串
语法:echo ${var/#str}
|
|
#下例表示删除字符串中行首的"H" # teststr="H.H.H.H.H.H" # echo ${teststr/#H} .H.H.H.H.H #下例表示删除字符串中行首的"#" # teststr="#zsy#think#linux" # echo ${teststr/##} zsy#think#linux |
特殊情况
|
|
参考之前的特殊情况,即可发现,由于删除字符串中行首的字符时需要使用语法"/#",所以如果想要删除字符串中第一个遇到的"#"时,则不能使用"/#",需要对"#"进行转义,示例如下,删除字符串中第一个遇到的"#" # teststr="zsy#think#linux" # echo ${teststr/\#} zsythink#linux |
删除变量值中位于行尾的指定字符串
语法:echo ${var/%str}
|
|
#下例表示删除字符串中行尾的"H" # teststr="H.H.H.H.H.H" # echo ${teststr/%H} H.H.H.H.H. #下例表示删除字符串中行尾的"%" # teststr="zsy%think%linux%" # echo ${teststr/%%} zsy%think%linux |
特殊情况
|
|
参考之前的特殊情况,即可发现,由于删除字符串中行尾的字符时需要使用语法"/%",所以如果想要删除字符串中第一个遇到的"%"时,则不能使用"/%",需要对"%"进行转义 #示例如下,删除字符串中第一个遇到的"%" # teststr="zsy%think%linux%" # echo ${teststr/\%} zsythink%linux% |
替换字符串的操作
将变量值中第一个遇到的str1替换成str2
语法:echo ${var/str1/str2}
|
|
#下例表示将字符串中第一个遇到的"w"替换成"abc" # teststr="www" # echo ${teststr/w/abc} abcww |
将变量值中所有的str1替换成str2
语法:echo ${var//str1/str2}
|
|
#下例表示将字符串中所有"w"替换成"abc" # teststr="www" # echo ${teststr//w/abc} abcabcabc |
特殊情况
|
|
某些情况下需要进行转义,参考"删除字符串操作"总结部分的特殊情况。 |
将变量值中位于行首的str1替换成str2
语法:echo ${var/#str1/str2}
|
|
#下例表示将字符串中位于行首的abc替换成123 # teststr="abcdefabc666abc888abc" # echo ${teststr/#abc/123} 123defabc666abc888abc |
特殊情况
|
|
某些情况下需要对#号进行转义,参考"删除字符串操作"总结部分的特殊情况。 |
将变量值中位于行尾的str1替换成str2
语法:echo ${var/%str1/str2}
|
|
#下例表示将字符串中位于行尾的abc替换成666 # teststr="abcdefabc666abc888abc" # echo ${teststr/%abc/666} abcdefabc666abc888666 |
特殊情况
|
|
某些情况下需要对%号进行转义,参考"删除字符串操作"总结部分的特殊情况。 |
好了,关于变量操作、字符串操作就总结到这里,希望这篇文章能够对你有所帮助。
2020年5月30日 下午5:00 沙发
真正的深入浅出。
2019年11月26日 上午11:27 板凳
[root@ali_mua shell]# cat test.sh
#!/bin/bash
workdir=
${workdir:-“ttt”}
echo $workdir
[root@ali_mua shell]# bash -x test.sh
+ workdir=
+ ttt
test.sh: line 3: ttt: command not found
+ echo
[root@ali_mua shell]# cat test.sh
#!/bin/bash
workdir=
${workdir:-“ls”}
echo $workdir
[root@ali_mua shell]# bash -x test.sh
+ workdir=
+ ls
pgsql test.sh
+ echo
大佬 , ${workdir:-“ttt”} 这个(ttt)貌似只能使用 系统命令,用任意字符串的话 脚本执行会提示command not found 替换成ls后就打印了当前目录下的文件
并且 最后 输出 的变量 是 空
不知道是不是内核、系统版本的问题 内核 是 4.19.57-15.1.al7.x86_64 系统是阿里的镜像Aliyun Linux release 2.1903 (Hunting Beagle)
2019年3月22日 下午9:36 地板
总结的特好,但是都说运维是吃青春饭,你怎么看
2019年4月4日 下午8:37 1层
@nc -l 520 ….互联网那个不是,,
2018年5月28日 上午9:56 4楼
博主的变量处理真的实用,不管是我自己在学习的shell脚本还是用别人脚本出错都能看的懂了。
2017年10月8日 下午4:43 5楼
朱兄,在掌握了LINUX基础后真的不知有什么工作可以找?
2017年10月9日 上午10:06 1层
@早 ……顺其自然吧兄弟,找一个基础运维的工作,入门就好了,加油~~